package com.zx._02_thread.线程池;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.zx.common.util.ThreadUtil;
import java.lang.Thread.State;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.util.ReflectionUtils;

public class 线程池中线程监控 {

    // 监控 ThreadPoolExecutor 中的私有属性 HashSet<Worker> workers
    public static final Field workersField;

    // 监控 ThreadPoolExecutor 的私有内部类 Worker 类中的thread属性
    public static Field workerClassThread;

    static {
        workersField = ReflectionUtils.findField(ThreadPoolExecutor.class, "workers");
        workersField.setAccessible(true);

        Class<?> workerClass = null;
        for (final Class<?> innerClass : ThreadPoolExecutor.class.getDeclaredClasses()) {
            // 获取修饰符的整数编码
            final int mod = innerClass.getModifiers();
            //返回整数编码对应的修饰符的字符串对象
            final String modifier = Modifier.toString(mod);
            if ("Worker".equals(innerClass.getSimpleName())
                    && modifier.contains("private")) {
                workerClass = innerClass;
            }
        }
        try {
            workerClassThread = workerClass.getDeclaredField("thread");
            workerClassThread.setAccessible(true);
        } catch (final NoSuchFieldException e) {
            e.printStackTrace();
        } catch (final SecurityException e) {
            e.printStackTrace();
        }
    }


    public static void main(final String[] args) throws Exception {
        final ThreadPoolExecutor pool = new ThreadPoolExecutor(3, 10, 1, TimeUnit.SECONDS,
                new LinkedBlockingQueue<Runnable>(5));

        // 1s一次监控
        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(1);
        scheduledThreadPool.scheduleAtFixedRate(() -> {
            List<ThreadState> stateList = getStateList(pool);
            System.out.println(JSON.toJSONString(stateList));
        }, 1, 1, TimeUnit.SECONDS);

        for (int i = 0; i < 100; i++) {

            ThreadUtil.sleepMill(200);

            pool.execute(() -> {
                ThreadUtil.sleep(1);         // 线程是TIMED_WAITING
//				LockSupport.park();					// 线程是WAITING
//				LockSupport.parkNanos(1000_000_000);// 线程是TIMED_WAITING
            });

        }

        pool.shutdown();


    }

    public static List<ThreadState> getStateList(final ThreadPoolExecutor pool) {
        List<ThreadState> resList = Lists.newArrayList();
        try {
            final HashSet<?> workers = (HashSet<?>) workersField.get(pool);
            for (final Object obj : workers) {
                final Thread innerThreadObj = (Thread) workerClassThread.get(obj);
                // 线程状态
                final State state = innerThreadObj.getState();
                // 线程名称
                final String name = innerThreadObj.getName();
                resList.add(new ThreadState(name, state.toString()));
            }
        } catch (final Exception e) {
            e.printStackTrace();
        }
        return resList;
    }


    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    private static class ThreadState {

        private String name;
        private String state;
    }

}
